﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Motoball.screenmanager;
using Motoball.screens;

namespace Motoball.Paddles
{

    public class Beamer : PaddleContent
    {
        
        bool beamed = false;
        float bloomMultiplier = 1f;
        
        public Beamer(Paddle paddle)
            : base(paddle)
        {
            animation = new BeamerAnimation();
            paddleWidth = 405;
            paddleHeight = 200;
            maxPaddleDistance = 620;//400;
            ballHeight = 2360f;
            type = "beamer";
        }

        #region Methods
        public override void Reset()
        {
            
            bloomMultiplier = 1f;
            beamed = false;
            
            base.Reset();
        }
        
        
        public override bool Update(GameTime gameTime)
        {
            if(!base.Update(gameTime))
            {
                //after 0.5 sec blooming has highest value - then starts to return to 0
                specialMoveTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                bloomValue += (float)gameTime.ElapsedGameTime.TotalSeconds * bloomMultiplier;
                if (bloomValue < 0)
                    bloomValue = 0;
                set.SetBloomValues(MathHelper.Lerp(1f, 30f, bloomValue * 4f));
                if (specialMoveTimer >= 0.25f && !beamed)
                {
                    BeamAcross();
                    specialMoveTimer = 0.25f;
                    bloomMultiplier = -1;
                    beamed = true;
                }
                else if (specialMoveTimer > 0.5f)
                {
                    SpecialMovement(false);
                    beamed = false;
                    bloomMultiplier = 1;
                    specialMoveTimer = 0;
                    bloomValue = 0;
                }

                return false;
            }
            return true;
        }
        public override void SpecialMovement(bool action)
        {
            base.SpecialMovement(action);
            movementDisabled = action;
            if(action)
                AudioManager.PlayCue("beam");
        }
        private void BeamAcross()
        {
            float newRotation = paddle.Rotation + MathHelper.Pi;
            if (newRotation > MathHelper.TwoPi)
                newRotation -= MathHelper.TwoPi;

            Matrix testSpace = Matrix.CreateRotationX(-MathHelper.PiOver2);
            testSpace *= Matrix.CreateTranslation(0.0f, 0.0f, paddle.InnerRadius);
            testSpace *= Matrix.CreateRotationY(newRotation);

            //test if paddle can beam straight ot the opposit side or if other paddle would intersect
            //if so set specialMoveActive paddle as close as possible
            if (Vector3.Distance(testSpace.Translation, paddle.OtherPaddle.World.Translation) <=
                paddle.PaddleWidth + paddle.OtherPaddle.PaddleWidth)
            {
                //minimum enemy rotation-difference
                float minPadDistance = 0.7f;

                float curEnemyRotationDistance = paddle.OtherPaddle.Rotation - newRotation;

                //if (curEnemyRotationDistance < -MathHelper.Pi)
                //        curEnemyRotationDistance = -MathHelper.TwoPi - curEnemyRotationDistance;
                //else if(curEnemyRotationDistance > MathHelper.Pi)
                //        curEnemyRotationDistance = MathHelper.TwoPi - curEnemyRotationDistance;

                //negative rotation to enemy (positive rotation needed)
                if (curEnemyRotationDistance < 0 && curEnemyRotationDistance > -MathHelper.Pi
                    || curEnemyRotationDistance > MathHelper.Pi)
                    newRotation += minPadDistance + curEnemyRotationDistance;

                //positive rotation to enemy (negative rotation needed)
                else
                    newRotation -= minPadDistance - curEnemyRotationDistance;
            }
            paddle.Rotation = newRotation;
        }
        public override void Initialize(float innerRadius)
        {
            base.Initialize(innerRadius);
            shield = new BoneProperties[2];
            shield[0] = new BoneProperties(paddle.basicModel.model.Bones["Chassis_Schild"]);
            shield[1] = new BoneProperties(paddle.basicModel.model.Bones["Chassis_Schild1"]);
            //paddle.basicModel.diffColors["Rad1"] = Vector3.Lerp(Vector3.One, paddle.Color, 0.2f);
            //paddle.basicModel.diffColors["Rad2"] = Vector3.Lerp(Vector3.One, paddle.Color, 0.2f);
            
        }
        public override void UpdateAnimation(GameTime gameTime)
        {
            base.UpdateAnimation(gameTime);
            animation.Draw(gameTime);
        }
        #endregion
    }

    public class BeamerAnimation : PaddleAnimation
    {
        BoneProperties[,,] ribs;

        double[] timer;

        public BeamerAnimation()
            : base()
        {
            ribs = new BoneProperties[2, 3, 2];
            timer = new double[3];
            timer[0] = 480;
            timer[1] = 240;
            timer[2] = 0;
        }
        BoneProperties[] additionalWheels;
        public override void Initialize(float innerRadius, Model model)
        {
            #if !XBOX
            save.fileName = "beamer";
            #endif
            base.Initialize(innerRadius, model);
            ribs[0, 0, 0] = new BoneProperties(model.Bones["Rippen1_1a"]);
            ribs[0, 1, 0] = new BoneProperties(model.Bones["Rippen1_2a"]);
            ribs[0, 2, 0] = new BoneProperties(model.Bones["Rippen1_3a"]);
            ribs[1, 0, 0] = new BoneProperties(model.Bones["Rippen2_3a"]);
            ribs[1, 1, 0] = new BoneProperties(model.Bones["Rippen2_2a"]);
            ribs[1, 2, 0] = new BoneProperties(model.Bones["Rippen2_1a"]);

            ribs[0, 0, 1] = new BoneProperties(model.Bones["Rippen1_1b"]);
            ribs[0, 1, 1] = new BoneProperties(model.Bones["Rippen1_2b"]);
            ribs[0, 2, 1] = new BoneProperties(model.Bones["Rippen1_3b"]);
            ribs[1, 0, 1] = new BoneProperties(model.Bones["Rippen2_3b"]);
            ribs[1, 1, 1] = new BoneProperties(model.Bones["Rippen2_2b"]);
            ribs[1, 2, 1] = new BoneProperties(model.Bones["Rippen2_1b"]);


            leftWheel = model.Bones["Rad1_Felge"];
            rightWheel = model.Bones["Rad2_Felge"];

            leftWheelTransform = leftWheel.Transform;
            rightWheelTransform = rightWheel.Transform;

            additionalWheels = new BoneProperties[2];
            additionalWheels[0] = new BoneProperties(model.Bones["Rad1_Reifen"]);
            additionalWheels[1] = new BoneProperties(model.Bones["Rad2_Reifen"]);
        }

        public override void UpdateColor(Vector3 color, BasicModel basicModel)
        {
            //basicModel.diffColors["Obj_000002"] = color;
            //basicModel.diffColors["Rad1_Felge"] = Vector3.Lerp(Vector3.One, color, 0.7f);
            basicModel.diffColors["Rad2_Felge"] = Vector3.Lerp(Vector3.One, color, 0.7f);

            //basicModel.diffColors["Rippen1_1b"] = Vector3.Lerp(Vector3.One, color, 0.6f);
            //basicModel.diffColors["Rippen2_1b"] = Vector3.Lerp(Vector3.One, color, 0.6f);

            //basicModel.diffColors["Rippen1_2a"] = Vector3.Lerp(Vector3.One, color, 0.5f);
            //basicModel.diffColors["Rippen2_2a"] = Vector3.Lerp(Vector3.One, color, 0.5f);

            //basicModel.diffColors["Rippen1_3a"] = Vector3.Lerp(Vector3.One, color, 0.4f);
            //basicModel.diffColors["Rippen2_3a"] = Vector3.Lerp(Vector3.One, color, 0.4f);

        }

        public override void UpdateAnimation(GameTime gameTime)
        {
            for (int i = 0; i < 3; i++)
            {
                timer[i] += gameTime.ElapsedGameTime.Milliseconds;
                float hoverFactor = (float)Math.Sin(timer[i] / 300) * 4.3f;
                for (int j = 0; j < 2; j++)
                {
                    for (int k = 0; k < 2; k++)
                    {
                        ribs[j, i, k].modelBone.Transform = Matrix.CreateTranslation(0, 0, hoverFactor) * ribs[j, i, k].sourceTransform;
                    }
                }
            }
            additionalWheels[0].modelBone.Transform = Matrix.CreateRotationY(wheelRotation) * additionalWheels[0].sourceTransform;
            additionalWheels[1].modelBone.Transform = Matrix.CreateRotationY(wheelRotation) * additionalWheels[1].sourceTransform;
            base.UpdateAnimation(gameTime);

        }   
    }
}
